/*
 * magiced_shared_record.hpp
 *
 *  Created on: 2023年5月16日
 *      Author: Dylan.Gao
 */

#ifndef _DM_OS_MAGICED_SHARED_RECORD_HPP_
#define _DM_OS_MAGICED_SHARED_RECORD_HPP_

#include <dm/os/types.hpp>
#include <dm/magic.hpp>

namespace dm{
namespace os{

/**
 * 具备魔数的共享记录
 * @tparam S
 */
template<typename S>
struct TSMagicedSharedRecord{
	typedef dm::CMagic::magic_t magic_t;

	upgradable_mutex_t mutex;	//!< 共享互斥量
	magic_t magic;	//!< 修改魔数
	S d;			//!< 数据内容

	/**
	 * 记录加载器类
	 */
	class CLoader{
	public:
		virtual ~CLoader(){}

		virtual bool loadRecord( S& record )=0;
	};

	/**
	 * 记录读取器类
	 */
	class CReader{
	public:
		virtual ~CReader(){}

		bool readRecord( const S& record,void* pTmp ){
			S* pSTmp = (S*)pTmp;
			*pSTmp = record;
			return true;
		}
	};

	/**
	 * 比较器类
	 */
	class CComparer{
	public:
		virtual ~CComparer(){}

		virtual bool compareById( const S& record,id_t id ){
			return false;
		}

		virtual bool compareByName( const S& record,const char* name ){
			return false;
		}

		virtual bool compareByAny( const S& record,const void* pTmp ){
			return false;
		}
	};

	class CCommonComparer:public CComparer{
	public:
		virtual bool compareById( const S& record,id_t id ){
			return record.id==id;
		}

		virtual bool compareByName( const S& record,const char* name ){
			return record.name==name;
		}
	};

	class CUpdater{
	public:
		virtual ~CUpdater(){}

		virtual bool updateRecord( S& record,void* pTmp ){
			S* pSTmp = (S*)pTmp;
			record = *pSTmp;

			return true;
		}
	};

	/**
	 * 加载记录
	 * @param loader
	 * @return
	 */
	bool reload( CLoader& loader ){
		boost::interprocess::scoped_lock<upgradable_mutex_t> scopedLock(mutex);
		try{
			return loader.loadRecord(d);
		}catch(...){
			return false;
		}
	}

	/**
	 * 读取记录
	 * @param reader
	 * @param pTmp
	 * @return
	 */
	bool read( CReader& reader,void* pTmp ){
		boost::interprocess::sharable_lock<upgradable_mutex_t> sharableLock(mutex);
		try{
			return reader.readRecord(d, pTmp);
		}catch(...){
			return false;
		}
	}

	bool compareById( CComparer& comparer,id_t id ){
		boost::interprocess::sharable_lock<upgradable_mutex_t> sharableLock(mutex);
		try{
			return comparer.compareById(d, id);
		}catch(...){
			return false;
		}
	}

	bool compareByName( CComparer& comparer,const char* name ){
		boost::interprocess::sharable_lock<upgradable_mutex_t> sharableLock(mutex);
		try{
			return comparer.compareByName(d, name);
		}catch(...){
			return false;
		}
	}

	bool compareByAny( CComparer& comparer,void* key ){
		boost::interprocess::sharable_lock<upgradable_mutex_t> sharableLock(mutex);
		try{
			return comparer.compareByAny(d, key);
		}catch(...){
			return false;
		}
	}

	/**
	 * 更新记录
	 * @param updater
	 * @param pTmp
	 * @return
	 */
	bool update( CUpdater& updater,void* pTmp ){
		boost::interprocess::scoped_lock<upgradable_mutex_t> scopedLock(mutex);
		try{
			return updater.updateRecord(d, pTmp);
		}catch(...){
			return false;
		}
	}
};

}
}



#endif /* _DM_OS_MAGICED_SHARED_RECORD_HPP_ */
